home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 March / macformat-022.iso / Shareware City / Developers / src / out-of-phase-102-c / OutOfPhase 1.02 Source / OutOfPhase Folder / FunctionList.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-23  |  23.1 KB  |  783 lines  |  [TEXT/KAHL]

  1. /* FunctionList.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "FunctionList.h"
  31. #include "StringList.h"
  32. #include "Memory.h"
  33. #include "CodeCenter.h"
  34. #include "Array.h"
  35. #include "FunctionObject.h"
  36. #include "Alert.h"
  37. #include "DataMunging.h"
  38. #include "MainWindowStuff.h"
  39. #include "BufferedFileInput.h"
  40. #include "BufferedFileOutput.h"
  41. #include "Files.h"
  42. #include "Scrap.h"
  43.  
  44.  
  45. struct FunctionListRec
  46.     {
  47.         StringListRec*                    List;
  48.         CodeCenterRec*                    CodeCenter;
  49.         struct MainWindowRec*        MainWindow;
  50.         ArrayRec*                                FunctionArray;
  51.         MyBoolean                                FunctionListChanged;
  52.     };
  53.  
  54.  
  55. #define MAGICSCRAPSTRING ("\xff\x00\x1f\xfe FunctionModuleScrap")
  56.  
  57.  
  58. /* create a new function list */
  59. FunctionListRec*        NewFunctionList(struct MainWindowRec* MainWindow,
  60.                                             struct CodeCenterRec* CodeCenter, WinType* ScreenID,
  61.                                             OrdType XLoc, OrdType YLoc, OrdType Width, OrdType Height)
  62.     {
  63.         FunctionListRec*    FuncList;
  64.  
  65.         FuncList = (FunctionListRec*)AllocPtrCanFail(sizeof(FunctionListRec),
  66.             "FunctionListRec");
  67.         if (FuncList == NIL)
  68.             {
  69.              FailurePoint1:
  70.                 return NIL;
  71.             }
  72.         FuncList->List = NewStringList(ScreenID,XLoc,YLoc,Width,Height,
  73.             GetScreenFont(),9,StringListDontAllowMultipleSelection,"Function Modules");
  74.         if (FuncList->List == NIL)
  75.             {
  76.              FailurePoint2:
  77.                 ReleasePtr((char*)FuncList);
  78.                 goto FailurePoint1;
  79.             }
  80.         FuncList->FunctionArray = NewArray();
  81.         if (FuncList->FunctionArray == NIL)
  82.             {
  83.              FailurePoint3:
  84.                 DisposeStringList(FuncList->List);
  85.                 goto FailurePoint2;
  86.             }
  87.         FuncList->MainWindow = MainWindow;
  88.         FuncList->CodeCenter = CodeCenter;
  89.         FuncList->FunctionListChanged = False;
  90.         return FuncList;
  91.     }
  92.  
  93.  
  94. /* delete the function list and all of the function modules it contains */
  95. void                                DisposeFunctionList(FunctionListRec* FuncList)
  96.     {
  97.         long                            Scan;
  98.         long                            Limit;
  99.  
  100.         CheckPtrExistence(FuncList);
  101.         Limit = ArrayGetLength(FuncList->FunctionArray);
  102.         for (Scan = 0; Scan < Limit; Scan += 1)
  103.             {
  104.                 FunctionObjectRec*    FunctionTemp;
  105.  
  106.                 FunctionTemp = (FunctionObjectRec*)ArrayGetElement(FuncList->FunctionArray,Scan);
  107.                 DisposeFunctionObject(FunctionTemp);
  108.             }
  109.         DisposeArray(FuncList->FunctionArray);
  110.         DisposeStringList(FuncList->List);
  111.         ReleasePtr((char*)FuncList);
  112.     }
  113.  
  114.  
  115. /* change the location of the function list in the window */
  116. void                                SetFunctionListLocation(FunctionListRec* FuncList,
  117.                                             OrdType XLoc, OrdType YLoc, OrdType Width, OrdType Height)
  118.     {
  119.         CheckPtrExistence(FuncList);
  120.         SetStringListLoc(FuncList->List,XLoc,YLoc,Width,Height);
  121.     }
  122.  
  123.  
  124. /* redraw the list */
  125. void                                FunctionListRedraw(FunctionListRec* FuncList)
  126.     {
  127.         CheckPtrExistence(FuncList);
  128.         RedrawStringList(FuncList->List);
  129.     }
  130.  
  131.  
  132. /* see if the specified coordinates falls inside the function list rectangle */
  133. MyBoolean                        FunctionListHitTest(FunctionListRec* FuncList,
  134.                                             OrdType XLoc, OrdType YLoc)
  135.     {
  136.         CheckPtrExistence(FuncList);
  137.         return StringListHitTest(FuncList->List,XLoc,YLoc);
  138.     }
  139.  
  140.  
  141. /* handle a mouse down event for the function list */
  142. void                                FunctionListDoMouseDown(FunctionListRec* FuncList, OrdType XLoc,
  143.                                             OrdType YLoc, ModifierFlags Modifiers)
  144.     {
  145.         CheckPtrExistence(FuncList);
  146.         if (StringListMouseDown(FuncList->List,XLoc,YLoc,Modifiers))
  147.             {
  148.                 /* if it returns true, then it was a double click */
  149.                 FunctionListOpenSelection(FuncList);
  150.             }
  151.     }
  152.  
  153.  
  154. /* called when the window becomes active */
  155. void                                FunctionListBecomeActive(FunctionListRec* FuncList)
  156.     {
  157.         CheckPtrExistence(FuncList);
  158.         EnableStringList(FuncList->List);
  159.     }
  160.  
  161.  
  162. /* called when the window becomes inactive */
  163. void                                FunctionListBecomeInactive(FunctionListRec* FuncList)
  164.     {
  165.         CheckPtrExistence(FuncList);
  166.         DisableStringList(FuncList->List);
  167.     }
  168.  
  169.  
  170. /* called when a selection is made in another list, so that this list */
  171. /* is deselected */
  172. void                                FunctionListDeselect(FunctionListRec* FuncList)
  173.     {
  174.         CheckPtrExistence(FuncList);
  175.         DeselectAllStringListElements(FuncList->List);
  176.     }
  177.  
  178.  
  179. /* check to see if there is a selection in this list */
  180. MyBoolean                        FunctionListIsThereSelection(FunctionListRec* FuncList)
  181.     {
  182.         CheckPtrExistence(FuncList);
  183.         return (GetStringListHowManySelectedItems(FuncList->List) > 0);
  184.     }
  185.  
  186.  
  187. /* check to see if any of the function modules contained in this list need */
  188. /* to be saved */
  189. MyBoolean                        DoesFunctionListNeedToBeSaved(FunctionListRec* FuncList)
  190.     {
  191.         long                            Scan;
  192.         long                            Limit;
  193.         MyBoolean                    Flag;
  194.  
  195.         CheckPtrExistence(FuncList);
  196.         Flag = FuncList->FunctionListChanged;
  197.         Limit = ArrayGetLength(FuncList->FunctionArray);
  198.         for (Scan = 0; (Scan < Limit) && !Flag; Scan += 1)
  199.             {
  200.                 FunctionObjectRec*    FunctionTemp;
  201.  
  202.                 FunctionTemp = (FunctionObjectRec*)ArrayGetElement(FuncList->FunctionArray,Scan);
  203.                 if (HasFunctionObjectBeenModified(FunctionTemp))
  204.                     {
  205.                         Flag = True;
  206.                     }
  207.             }
  208.         return Flag;
  209.     }
  210.  
  211.  
  212. /* open an edit window for the selected function module */
  213. void                                FunctionListOpenSelection(FunctionListRec* FuncList)
  214.     {
  215.         ArrayRec*                    ListOfSelections;
  216.  
  217.         CheckPtrExistence(FuncList);
  218.         ListOfSelections = GetListOfSelectedItems(FuncList->List);
  219.         if (ListOfSelections != NIL)
  220.             {
  221.                 long                            Scan;
  222.                 long                            Limit;
  223.  
  224.                 Limit = ArrayGetLength(ListOfSelections);
  225.                 for (Scan = 0; Scan < Limit; Scan += 1)
  226.                     {
  227.                         FunctionObjectRec*        FunctionTemp;
  228.  
  229.                         FunctionTemp = (FunctionObjectRec*)ArrayGetElement(ListOfSelections,Scan);
  230.                         FunctionObjectOpenWindow(FunctionTemp);
  231.                     }
  232.                 DisposeArray(ListOfSelections);
  233.             }
  234.     }
  235.  
  236.  
  237. /* create a new function module and open a window for it */
  238. void                                FunctionListNewModule(FunctionListRec* FuncList)
  239.     {
  240.         FunctionObjectRec*    Function;
  241.  
  242.         CheckPtrExistence(FuncList);
  243.         /* create the object */
  244.         Function = NewFunctionObject(FuncList->CodeCenter,FuncList->MainWindow,FuncList);
  245.         if (Function == NIL)
  246.             {
  247.              FailurePoint1:
  248.                 AlertHalt("There is not enough memory available to create "
  249.                     "a new function module.",NIL);
  250.                 return;
  251.             }
  252.         /* add it to the string list */
  253.         if (!InsertStringListElement(FuncList->List,NIL,NIL,Function,True))
  254.             {
  255.              FailurePoint2:
  256.                 DisposeFunctionObject(Function);
  257.                 goto FailurePoint1;
  258.             }
  259.         MainWindowDeselectAllOtherStringLists(FuncList->MainWindow,FuncList);
  260.         SelectStringListElement(FuncList->List,Function);
  261.         MakeStringListSelectionVisible(FuncList->List);
  262.         /* add it to the array */
  263.         if (!ArrayAppendElement(FuncList->FunctionArray,Function))
  264.             {
  265.              FailurePoint3:
  266.                 RemoveStringListElement(FuncList->List,Function,True);
  267.                 goto FailurePoint2;
  268.             }
  269.         /* update our internal flags */
  270.         FuncList->FunctionListChanged = True;
  271.         /* change the name in the list */
  272.         FunctionListFunctionNameChanged(FuncList,Function);
  273.         /* show the window */
  274.         FunctionObjectOpenWindow(Function);
  275.     }
  276.  
  277.  
  278. /* delete the selected function module */
  279. void                                FunctionListDeleteSelection(FunctionListRec* FuncList)
  280.     {
  281.         ArrayRec*                    ListOfSelections;
  282.  
  283.         CheckPtrExistence(FuncList);
  284.         ListOfSelections = GetListOfSelectedItems(FuncList->List);
  285.         if (ListOfSelections != NIL)
  286.             {
  287.                 long                                Scan;
  288.                 long                                Limit;
  289.  
  290.                 Limit = ArrayGetLength(ListOfSelections);
  291.                 for (Scan = 0; Scan < Limit; Scan += 1)
  292.                     {
  293.                         FunctionObjectRec*    OneToZap;
  294.  
  295.                         OneToZap = (FunctionObjectRec*)ArrayGetElement(ListOfSelections,Scan);
  296.                         FunctionListDeleteFunction(FuncList,OneToZap);
  297.                     }
  298.                 DisposeArray(ListOfSelections);
  299.             }
  300.     }
  301.  
  302.  
  303. /* delete the explicitly specified function module */
  304. void                                FunctionListDeleteFunction(FunctionListRec* FuncList,
  305.                                             struct FunctionObjectRec* TheFunctionModule)
  306.     {
  307.         long                                Scan;
  308.         long                                Limit;
  309.  
  310.         CheckPtrExistence(FuncList);
  311.         Limit = ArrayGetLength(FuncList->FunctionArray);
  312.         for (Scan = 0; Scan < Limit; Scan += 1)
  313.             {
  314.                 FunctionObjectRec*        FunctionTemp;
  315.  
  316.                 FunctionTemp = (FunctionObjectRec*)ArrayGetElement(FuncList->FunctionArray,Scan);
  317.                 if (TheFunctionModule == FunctionTemp)
  318.                     {
  319.                         FileSpec*                    BackupFileWhere;
  320.                         FileType*                    BackupFile;
  321.                         MyBoolean                    Success = False;
  322.  
  323.                         BackupFileWhere = NewTempFileSpec(CODE4BYTES('?','?','?','?'),
  324.                             CODE4BYTES('?','?','?','?'));
  325.                         if (BackupFileWhere != NIL)
  326.                             {
  327.                                 if (OpenFile(BackupFileWhere,&BackupFile,eReadAndWrite))
  328.                                     {
  329.                                         BufferedOutputRec*    Output;
  330.  
  331.                                         Output = NewBufferedOutput(BackupFile);
  332.                                         if (Output != NIL)
  333.                                             {
  334.                                                 if (WriteBufferedOutput(Output,sizeof(MAGICSCRAPSTRING),
  335.                                                     MAGICSCRAPSTRING))
  336.                                                     {
  337.                                                         if (FunctionObjectWriteOutData(TheFunctionModule,Output)
  338.                                                             == eFileLoadNoError)
  339.                                                             {
  340.                                                                 Success = True;
  341.                                                             }
  342.                                                     }
  343.                                                 if (!EndBufferedOutput(Output))
  344.                                                     {
  345.                                                         Success = False;
  346.                                                     }
  347.                                             }
  348.                                          else
  349.                                             {
  350.                                                 CloseFile(BackupFile);
  351.                                             }
  352.                                     }
  353.                                  else
  354.                                     {
  355.                                         DeleteFile(BackupFileWhere);
  356.                                         DisposeFileSpec(BackupFileWhere);
  357.                                     }
  358.                             }
  359.                         if (Success)
  360.                             {
  361.                                 MainWindowNewDeleteUndoInfo(FuncList->MainWindow,BackupFileWhere,
  362.                                     BackupFile);
  363.                                 DisposeFunctionObject(FunctionTemp);
  364.                                 RemoveStringListElement(FuncList->List,FunctionTemp,True);
  365.                                 ArrayDeleteElement(FuncList->FunctionArray,Scan);
  366.                                 FuncList->FunctionListChanged = True;
  367.                             }
  368.                          else
  369.                             {
  370.                                 YesNoCancelType        Decision;
  371.  
  372.                                 Decision = AskYesNoCancel("Unable to save undo information for object.  "
  373.                                     "Delete object anyway?",NIL,"Delete","Cancel",NIL/*nothirdbutton*/);
  374.                                 if (Decision == eYes)
  375.                                     {
  376.                                         DisposeFunctionObject(FunctionTemp);
  377.                                         RemoveStringListElement(FuncList->List,FunctionTemp,True);
  378.                                         ArrayDeleteElement(FuncList->FunctionArray,Scan);
  379.                                         FuncList->FunctionListChanged = True;
  380.                                     }
  381.                             }
  382.                         return;
  383.                     }
  384.             }
  385.         EXECUTE(PRERR(AllowResume,"FunctionListDeleteFunction:  couldn't find object"));
  386.     }
  387.  
  388.  
  389. /* the name of a function module has changed, so the name in the scrolling */
  390. /* list must also be changed */
  391. void                                FunctionListFunctionNameChanged(FunctionListRec* FuncList,
  392.                                             struct FunctionObjectRec* TheFunctionModule)
  393.     {
  394.         char*                            FunctionName;
  395.  
  396.         CheckPtrExistence(FuncList);
  397.         CheckPtrExistence(TheFunctionModule);
  398.         ERROR(ArrayFindElement(FuncList->FunctionArray,TheFunctionModule) < 0,
  399.             PRERR(ForceAbort,"FunctionListFunctionNameChanged:  unknown function"));
  400.         FunctionName = FunctionObjectGetNameCopy(TheFunctionModule);
  401.         if (FunctionName != NIL)
  402.             {
  403.                 char*                            FunctionNameNullTerminated;
  404.  
  405.                 FunctionNameNullTerminated = BlockToStringCopy(FunctionName);
  406.                 if (FunctionNameNullTerminated != NIL)
  407.                     {
  408.                         ChangeStringListElementName(FuncList->List,
  409.                             FunctionNameNullTerminated,TheFunctionModule);
  410.                         ReleasePtr(FunctionNameNullTerminated);
  411.                     }
  412.                 ReleasePtr(FunctionName);
  413.             }
  414.     }
  415.  
  416.  
  417. /* remove all object code for all function modules */
  418. void                                FunctionListUnbuildAll(FunctionListRec* FuncList)
  419.     {
  420.         long                            Scan;
  421.         long                            Limit;
  422.  
  423.         CheckPtrExistence(FuncList);
  424.         Limit = ArrayGetLength(FuncList->FunctionArray);
  425.         for (Scan = 0; Scan < Limit; Scan += 1)
  426.             {
  427.                 FunctionObjectRec*    FunctionTemp;
  428.  
  429.                 FunctionTemp = (FunctionObjectRec*)ArrayGetElement(FuncList->FunctionArray,Scan);
  430.                 FunctionObjectUnbuild(FunctionTemp);
  431.             }
  432.         ERROR(CodeCenterGetNumFunctions(FuncList->CodeCenter) != 0,PRERR(ForceAbort,
  433.             "FunctionListUnbuildAll:  some objects still exist"));
  434.     }
  435.  
  436.  
  437. /* build all functions.  returns True if successful. */
  438. MyBoolean                        FunctionListMakeUpToDate(FunctionListRec* FuncList)
  439.     {
  440.         long                            Scan;
  441.         long                            Limit;
  442.  
  443.         CheckPtrExistence(FuncList);
  444.         Limit = ArrayGetLength(FuncList->FunctionArray);
  445.         for (Scan = 0; Scan < Limit; Scan += 1)
  446.             {
  447.                 FunctionObjectRec*    FunctionTemp;
  448.  
  449.                 FunctionTemp = (FunctionObjectRec*)ArrayGetElement(FuncList->FunctionArray,Scan);
  450.                 if (!FunctionObjectMakeUpToDate(FunctionTemp))
  451.                     {
  452.                         return False;
  453.                     }
  454.             }
  455.         return True;
  456.     }
  457.  
  458.  
  459. /* the document's name has changed, so update all windows */
  460. void                                FunctionListGlobalNameChange(FunctionListRec* FuncList,
  461.                                             char* NewFilename)
  462.     {
  463.         long                            Scan;
  464.         long                            Limit;
  465.  
  466.         CheckPtrExistence(FuncList);
  467.         Limit = ArrayGetLength(FuncList->FunctionArray);
  468.         for (Scan = 0; Scan < Limit; Scan += 1)
  469.             {
  470.                 FunctionObjectRec*    FunctionTemp;
  471.  
  472.                 FunctionTemp = (FunctionObjectRec*)ArrayGetElement(FuncList->FunctionArray,Scan);
  473.                 FunctionObjectGlobalNameChange(FunctionTemp,NewFilename);
  474.             }
  475.     }
  476.  
  477.  
  478. /*   4-byte little endian function object count (positive 2s complement) */
  479. /*   n-bytes of data for the function objects */
  480.  
  481.  
  482. /* read function objects from a file.  returns True if completely successful. */
  483. FileLoadingErrors        FunctionListReadData(FunctionListRec* FuncList,
  484.                                             struct BufferedInputRec* Input)
  485.     {
  486.         long                            FunctionObjectCount;
  487.         long                            Scan;
  488.  
  489.         CheckPtrExistence(FuncList);
  490.         CheckPtrExistence(Input);
  491.  
  492.         /*   4-byte little endian function object count */
  493.         if (!ReadBufferedSignedLongLittleEndian(Input,&FunctionObjectCount))
  494.             {
  495.                 return eFileLoadDiskError;
  496.             }
  497.         if (FunctionObjectCount < 0)
  498.             {
  499.                 return eFileLoadBadFormat;
  500.             }
  501.  
  502.         /* read in all of the objects */
  503.         for (Scan = 0; Scan < FunctionObjectCount; Scan += 1)
  504.             {
  505.                 FunctionObjectRec*    FunctionTemp EXECUTE(= (FunctionObjectRec*)0x81818181);
  506.                 FileLoadingErrors        Error;
  507.  
  508.                 /* create the new function object */
  509.                 Error = FunctionObjectNewFromFile(&FunctionTemp,Input,FuncList->CodeCenter,
  510.                     FuncList->MainWindow,FuncList);
  511.                 if (Error != eFileLoadNoError)
  512.                     {
  513.                      FailurePoint1:
  514.                         return Error;
  515.                     }
  516.                 CheckPtrExistence(FunctionTemp);
  517.                 /* add it to the scrolling object list */
  518.                 if (!InsertStringListElement(FuncList->List,NIL,NIL,FunctionTemp,True))
  519.                     {
  520.                      FailurePoint2:
  521.                         DisposeFunctionObject(FunctionTemp);
  522.                         Error = eFileLoadOutOfMemory;
  523.                         goto FailurePoint1;
  524.                     }
  525.                 /* add it to the array */
  526.                 if (!ArrayAppendElement(FuncList->FunctionArray,FunctionTemp))
  527.                     {
  528.                      FailurePoint3:
  529.                         RemoveStringListElement(FuncList->List,FunctionTemp,True);
  530.                         goto FailurePoint2;
  531.                     }
  532.                 /* change the name in the list */
  533.                 FunctionListFunctionNameChanged(FuncList,FunctionTemp);
  534.             }
  535.  
  536.         return eFileLoadNoError;
  537.     }
  538.  
  539.  
  540. /* write function objects to a file.  returns True if completely successful. */
  541. FileLoadingErrors        FunctionListWriteData(FunctionListRec* FuncList,
  542.                                             struct BufferedOutputRec* Output)
  543.     {
  544.         long                            NumObjects;
  545.         long                            Scan;
  546.  
  547.         CheckPtrExistence(FuncList);
  548.         CheckPtrExistence(Output);
  549.  
  550.         /*   4-byte little endian function object count */
  551.         NumObjects = ArrayGetLength(FuncList->FunctionArray);
  552.         if (!WriteBufferedSignedLongLittleEndian(Output,NumObjects))
  553.             {
  554.                 return eFileLoadDiskError;
  555.             }
  556.  
  557.         /* write those little buggers out */
  558.         for (Scan = 0; Scan < NumObjects; Scan += 1)
  559.             {
  560.                 FunctionObjectRec*    FunctionTemp;
  561.                 FileLoadingErrors        Error;
  562.  
  563.                 /* get the thing */
  564.                 FunctionTemp = (FunctionObjectRec*)ArrayGetElement(FuncList->FunctionArray,Scan);
  565.                 /* write it */
  566.                 Error = FunctionObjectWriteOutData(FunctionTemp,Output);
  567.                 /* handle any bad things */
  568.                 if (Error != eFileLoadNoError)
  569.                     {
  570.                         return Error;
  571.                     }
  572.             }
  573.  
  574.         return eFileLoadNoError;
  575.     }
  576.  
  577.  
  578. /* after a file has been saved, this is called to mark all objects as not modified. */
  579. void                                FunctionListMarkAllObjectsSaved(FunctionListRec* FuncList)
  580.     {
  581.         long                            Scan;
  582.         long                            Limit;
  583.  
  584.         CheckPtrExistence(FuncList);
  585.         Limit = ArrayGetLength(FuncList->FunctionArray);
  586.         for (Scan = 0; Scan < Limit; Scan += 1)
  587.             {
  588.                 FunctionObjectRec*    FunctionTemp;
  589.  
  590.                 FunctionTemp = (FunctionObjectRec*)ArrayGetElement(FuncList->FunctionArray,Scan);
  591.                 FunctionObjectMarkAsSaved(FunctionTemp);
  592.             }
  593.         FuncList->FunctionListChanged = False;
  594.     }
  595.  
  596.  
  597. /* copy the selected object in the list to the clipboard.  return False if failed. */
  598. MyBoolean                        FunctionListCopyObject(FunctionListRec* FuncList)
  599.     {
  600.         ArrayRec*                            ListOfSelections;
  601.         MyBoolean                            TotalSuccessFlag = False;
  602.  
  603.         CheckPtrExistence(FuncList);
  604.         ListOfSelections = GetListOfSelectedItems(FuncList->List);
  605.         if (ListOfSelections != NIL)
  606.             {
  607.                 if (ArrayGetLength(ListOfSelections) >= 1)
  608.                     {
  609.                         FunctionObjectRec*    FunctionTemp;
  610.                         FileSpec*                        TempFileLocation;
  611.  
  612.                         FunctionTemp = (FunctionObjectRec*)ArrayGetElement(ListOfSelections,0);
  613.                         /* open the temporary file */
  614.                         TempFileLocation = NewTempFileSpec(CODE4BYTES('\?','\?','\?','\?'),
  615.                             CODE4BYTES('\?','\?','\?','\?'));
  616.                         if (TempFileLocation != NIL)
  617.                             {
  618.                                 FileType*                            FileDescriptor;
  619.  
  620.                                 if (OpenFile(TempFileLocation,&FileDescriptor,eReadAndWrite))
  621.                                     {
  622.                                         BufferedOutputRec*        BufferedFile;
  623.  
  624.                                         BufferedFile = NewBufferedOutput(FileDescriptor);
  625.                                         if (BufferedFile != NIL)
  626.                                             {
  627.                                                 MyBoolean                            WriteSucceeded = False;
  628.  
  629.                                                 if (WriteBufferedOutput(BufferedFile,sizeof(MAGICSCRAPSTRING),
  630.                                                     MAGICSCRAPSTRING))
  631.                                                     {
  632.                                                         if (FunctionObjectWriteOutData(FunctionTemp,BufferedFile)
  633.                                                             == eFileLoadNoError)
  634.                                                             {
  635.                                                                 WriteSucceeded = True;
  636.                                                             }
  637.                                                     }
  638.                                                 if (EndBufferedOutput(BufferedFile) && WriteSucceeded)
  639.                                                     {
  640.                                                         char*                            Buffer;
  641.                                                         long                            NumberOfBytes;
  642.  
  643.                                                         NumberOfBytes = GetFileLength(FileDescriptor);
  644.                                                         Buffer = AllocPtrCanFail(NumberOfBytes,
  645.                                                             "FunctionListCopyObject:  scrap buffer");
  646.                                                         if (Buffer != NIL)
  647.                                                             {
  648.                                                                 if (SetFilePosition(FileDescriptor,0))
  649.                                                                     {
  650.                                                                         if (0 == ReadFromFile(FileDescriptor,
  651.                                                                             Buffer,NumberOfBytes))
  652.                                                                             {
  653.                                                                                 if (SetScrapToThis(Buffer))
  654.                                                                                     {
  655.                                                                                         TotalSuccessFlag = True;
  656.                                                                                     }
  657.                                                                             }
  658.                                                                     }
  659.                                                                 ReleasePtr(Buffer);
  660.                                                             }
  661.                                                     }
  662.                                             }
  663.                                         CloseFile(FileDescriptor);
  664.                                     }
  665.                                 DeleteFile(TempFileLocation);
  666.                                 DisposeFileSpec(TempFileLocation);
  667.                             }
  668.                     }
  669.                 DisposeArray(ListOfSelections);
  670.             }
  671.         return TotalSuccessFlag;
  672.     }
  673.  
  674.  
  675. /* try to paste the clipboard in as a function object.  returns False if it failed */
  676. /* or the clipboard did not contain a function object. */
  677. MyBoolean                        FunctionListPasteObject(FunctionListRec* FuncList)
  678.     {
  679.         MyBoolean                    TotalSuccessFlag = False;
  680.         char*                            Scrap;
  681.  
  682.         CheckPtrExistence(FuncList);
  683.         Scrap = GetCopyOfScrap();
  684.         if (Scrap != NIL)
  685.             {
  686.                 FileSpec*                    TempFileLocation;
  687.  
  688.                 TempFileLocation = NewTempFileSpec(CODE4BYTES('\?','\?','\?','\?'),
  689.                     CODE4BYTES('\?','\?','\?','\?'));
  690.                 if (TempFileLocation != NIL)
  691.                     {
  692.                         FileType*                            FileDescriptor;
  693.  
  694.                         if (OpenFile(TempFileLocation,&FileDescriptor,eReadAndWrite))
  695.                             {
  696.                                 BufferedOutputRec*        BufferedFile;
  697.  
  698.                                 BufferedFile = NewBufferedOutput(FileDescriptor);
  699.                                 if (BufferedFile != NIL)
  700.                                     {
  701.                                         MyBoolean                            WriteSucceeded = False;
  702.  
  703.                                         if (WriteBufferedOutput(BufferedFile,PtrSize(Scrap),Scrap))
  704.                                             {
  705.                                                 WriteSucceeded = True;
  706.                                             }
  707.                                         if (EndBufferedOutput(BufferedFile) && WriteSucceeded)
  708.                                             {
  709.                                                 TotalSuccessFlag = FunctionListPasteFromFile(FuncList,
  710.                                                     FileDescriptor);
  711.                                             }
  712.                                     }
  713.                                 CloseFile(FileDescriptor);
  714.                             }
  715.                         DeleteFile(TempFileLocation);
  716.                         DisposeFileSpec(TempFileLocation);
  717.                     }
  718.                 ReleasePtr(Scrap);
  719.             }
  720.         return TotalSuccessFlag;
  721.     }
  722.  
  723.  
  724. /* try to paste a function object in from a file */
  725. MyBoolean                        FunctionListPasteFromFile(FunctionListRec* FuncList,
  726.                                             struct FileType* File)
  727.     {
  728.         MyBoolean                    TotalSuccessFlag = False;
  729.  
  730.         CheckPtrExistence(FuncList);
  731.         if (SetFilePosition(File,0))
  732.             {
  733.                 BufferedInputRec*    InputFile;
  734.  
  735.                 InputFile = NewBufferedInput(File);
  736.                 if (InputFile != NIL)
  737.                     {
  738.                         char                            HeaderTest[sizeof(MAGICSCRAPSTRING)];
  739.  
  740.                         if (ReadBufferedInput(InputFile,sizeof(MAGICSCRAPSTRING),HeaderTest))
  741.                             {
  742.                                 if (MemEqu(MAGICSCRAPSTRING,HeaderTest,sizeof(MAGICSCRAPSTRING)))
  743.                                     {
  744.                                         FunctionObjectRec*        FunctionTemp EXECUTE(= (FunctionObjectRec*)0x81818181);
  745.  
  746.                                         if (eFileLoadNoError == FunctionObjectNewFromFile(&FunctionTemp,
  747.                                             InputFile,FuncList->CodeCenter,FuncList->MainWindow,FuncList))
  748.                                             {
  749.                                                 CheckPtrExistence(FunctionTemp);
  750.                                                 /* add it to the scrolling object list */
  751.                                                 if (!InsertStringListElement(FuncList->List,NIL,NIL,FunctionTemp,True))
  752.                                                     {
  753.                                                      FailurePoint:
  754.                                                         DisposeFunctionObject(FunctionTemp);
  755.                                                     }
  756.                                                  else
  757.                                                     {
  758.                                                         MainWindowDeselectAllOtherStringLists(FuncList->MainWindow,FuncList);
  759.                                                         SelectStringListElement(FuncList->List,FunctionTemp);
  760.                                                         MakeStringListSelectionVisible(FuncList->List);
  761.                                                         /* add it to the array */
  762.                                                         if (!ArrayAppendElement(FuncList->FunctionArray,FunctionTemp))
  763.                                                             {
  764.                                                                 RemoveStringListElement(FuncList->List,FunctionTemp,True);
  765.                                                                 goto FailurePoint;
  766.                                                             }
  767.                                                          else
  768.                                                             {
  769.                                                                 /* change the name in the list */
  770.                                                                 FunctionListFunctionNameChanged(FuncList,FunctionTemp);
  771.                                                                 TotalSuccessFlag = True;
  772.                                                                 FuncList->FunctionListChanged = True;
  773.                                                             }
  774.                                                     }
  775.                                             }
  776.                                     }
  777.                             }
  778.                         EndBufferedInput(InputFile);
  779.                     }
  780.             }
  781.         return TotalSuccessFlag;
  782.     }
  783.